using System.Resources;
using System.Reflection;
using System.Drawing;
using System.Runtime.InteropServices;
using System.IO;
using System.Xml;
using System.Threading;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using System;
using System.ComponentModel.Design;


namespace GML.BizTalk.ContextAdderPipelineComponent
{
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("44BB4A78-818A-4c43-ADB9-F3D65F400B72"), CLSCompliant(false)]
	internal interface IBizTalkBuildSnapShot
	{
		object GetCompilableFiles();
		[return: MarshalAs(UnmanagedType.IUnknown)]
		object GetCommonProjectProperties();
		[return: MarshalAs(UnmanagedType.IUnknown)]
		object GetConfigProperties();
		object GetReferences();
		[return: MarshalAs(UnmanagedType.BStr)]
		string GetTempAssemblyPath();
	}

	public class ContextValueCollectionEditor : System.Drawing.Design.UITypeEditor//  CollectionEditor
	{
		public ContextValueCollectionEditor()
		{
			_editor = new CollectionEditor(typeof(ContextValueCollection));
			
		}
		CollectionEditor _editor;
		public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
		{
			return _editor.GetEditStyle (context);
		}

		public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			
			try
			{
				Type t = context.Instance.GetType();
				FieldInfo fi = t.GetField("pipelineFileComponentInfo",BindingFlags.Instance|BindingFlags.NonPublic);
				object ci = fi.GetValue(context.Instance);
				Type t2 = ci.GetType();
				PropertyInfo dirty = t2.GetProperty("Dirty",BindingFlags.Instance|BindingFlags.NonPublic);
				dirty.SetValue(ci,true,null);
			}
			catch
			{}
			//this is to get the build system to call save on the contextadder
			//object since its property is a collection
			//this is the code that is inside of the built-in pipeline collection editors
			//for some reason it didn't work for me
//			IServiceProvider provider2 = context.Instance as IServiceProvider;
//			if(provider2==null)
//				return value;
//			IntPtr ptr1 = IntPtr.Zero;
//			ptr1 = (IntPtr) provider2.GetService(typeof(IBizTalkBuildSnapShot));
//			if (ptr1 != IntPtr.Zero)
//			{
//				Marshal.GetObjectForIUnknown(ptr1);
//				Marshal.Release(ptr1);
//			}

			return _editor.EditValue (context, provider, value);
		}
	

	}
	public delegate void IsDirty();

	//[System.ComponentModel.Editor(typeof(System.ComponentModel.Design.CollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]
	[System.ComponentModel.Editor("ContextAdderHelper.ContextValueCollectionEditor",typeof(System.Drawing.Design.UITypeEditor))]
	public class ContextValueCollection : System.Collections.CollectionBase
	{
		protected override void OnInsert(int index, object value)
		{
			FireDirty();
			ContextValue cv = (ContextValue)value;
			cv.Dirty+=new IsDirty(this.FireDirty);
			base.OnInsert (index, value);
		}

		void FireDirty()
		{
			if(Dirty!=null)
				Dirty();
		}
		public event IsDirty Dirty;
		
		public ContextValue this[int index]
		{
			get{return (ContextValue)this.InnerList[index];}
			set{this.InnerList[index] = value;}
		}

	}
	public class ContextValue
	{
		internal event IsDirty Dirty;
		void LocalDirty()
		{
			if(Dirty!=null)
				Dirty();
		}
		public bool Promote
		{
			get{return _Promote;}
			set
			{
				LocalDirty();
				_Promote = value;}
		}
		public string Value
		{
			get{return _Value;}
			set
			{
				LocalDirty();
				_Value = value;}
		}
		public string Key
		{
			get{return _Key;}
			set
			{
				LocalDirty();
				_Key = value;}
		}
		public string Namespace
		{
			get{return _Namespace;}
			set
			{
				LocalDirty();
				_Namespace=value;}
		}
		string _Namespace;
		string _Value;
		string _Key;
		bool _Promote;
	}
}
